package com.fulin.jvm.classLoader.myloader;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class MyClassLoader extends ClassLoader{

    private String loaderClassName;

    private String path;

    private String loaderExtName = ".class";

    public void setPath(String path) {
        this.path = path;
    }

    public static void main(String[] args) throws Exception {
        MyClassLoader myClassLoader = new MyClassLoader("loader1");
        myClassLoader.setPath("C:\\Users\\fulin\\Desktop\\");
        Class<?> clazz = myClassLoader.loadClass("com.fulin.jvm.classLoader.Single");
        System.out.println(clazz.getClassLoader());
        Object instance = clazz.newInstance();
        System.out.println(instance);

        MyClassLoader myClassLoader2 = new MyClassLoader(myClassLoader,"loader2");
        myClassLoader2.setPath("C:\\Users\\fulin\\Desktop\\");
        Class<?> clazz2 = myClassLoader2.loadClass("com.fulin.jvm.classLoader.Single");
        System.out.println(clazz2.getClassLoader());
        Object instance2 = clazz2.newInstance();
        System.out.println(instance2);
    }

    public MyClassLoader(String loaderClassName) {
        super();
        this.loaderClassName = loaderClassName;
    }

    public MyClassLoader(ClassLoader parent, String loaderClassName) {
        super(parent);
        this.loaderClassName = loaderClassName;
    }


    @Override
    protected Class<?> findClass(String className) throws ClassNotFoundException {
        System.out.println("start findClass");
        byte[] byteData = findByteData(className);
        return defineClass(className,byteData,0,byteData.length);
    }

    private byte[] findByteData(String className){
        InputStream is = null;
        byte[] data = null;
        ByteArrayOutputStream bos = null;

        className = className.replace(".","\\");
        try{
            this.loaderClassName = this.loaderClassName.replace(".","/");
            is = new FileInputStream(new File(path + className + this.loaderExtName));
            bos = new ByteArrayOutputStream();
            int ch = 0;
            while(-1 != (ch = is.read())){
                bos.write(ch);
            }
            data = bos.toByteArray();
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            try{
                is.close();
                bos.close();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        return data;
    }
}
